// 版权归Go作者所有。版权所有。
// 此源代码的使用受BSD样式的约束
// 可以在许可证文件中找到的许可证。

package s390x

import (
	"fmt"
)

// CCMask表示4位条件代码掩码。点点滴滴
// 不属于掩码的部分应为0。
// None
// 条件代码掩码表示的4个可能值
// 2位条件代码作为单个位。自从IBM Z
// 是一个大端平台位从左到右编号
// 正当最低值0由8（0b1000）表示
// 最高值3由1（0b0001）表示。
// None
// 请注意，条件代码值具有不同的语义
// 取决于设置条件代码的指令。
// 此处给出的名称假定条件代码为
// 由整数或浮点比较设置。另外
// 说明可能会使用这些相同的代码来指示
// 不同的结果，如进位或溢出。
type CCMask uint8

const (
	Never CCMask = 0 // 无操作

	// 1位掩码
	Equal     CCMask = 1 << 3
	Less      CCMask = 1 << 2
	Greater   CCMask = 1 << 1
	Unordered CCMask = 1 << 0

	// 2位掩码
	EqualOrUnordered   CCMask = Equal | Unordered   // 不小不大
	LessOrEqual        CCMask = Less | Equal        // 有序而非更大
	LessOrGreater      CCMask = Less | Greater      // 有序而不平等
	LessOrUnordered    CCMask = Less | Unordered    // 不大于也不等于
	GreaterOrEqual     CCMask = Greater | Equal     // 有条不紊
	GreaterOrUnordered CCMask = Greater | Unordered // 不少于也不等于

	// 3位掩码
	NotEqual     CCMask = Always ^ Equal
	NotLess      CCMask = Always ^ Less
	NotGreater   CCMask = Always ^ Greater
	NotUnordered CCMask = Always ^ Unordered

	// 4位掩码
	Always CCMask = Equal | Less | Greater | Unordered

	// 有用的别名
	Carry    CCMask = GreaterOrUnordered
	NoCarry  CCMask = LessOrEqual
	Borrow   CCMask = NoCarry
	NoBorrow CCMask = Carry
)

// 反向返回条件代码掩码的补码。
func (c CCMask) Inverse() CCMask {
	return c ^ Always
}

// 反向比较交换掩码中0b0100和0b0010处的位，
// 反转大于和小于条件的行为。
func (c CCMask) ReverseComparison() CCMask {
	r := c & EqualOrUnordered
	if c&Less != 0 {
		r |= Greater
	}
	if c&Greater != 0 {
		r |= Less
	}
	return r
}

func (c CCMask) String() string {
	switch c {
	// 0位掩码
	case Never:
		return "Never"

	// 1位掩码
	case Equal:
		return "Equal"
	case Less:
		return "Less"
	case Greater:
		return "Greater"
	case Unordered:
		return "Unordered"

	// 2位掩码
	case EqualOrUnordered:
		return "EqualOrUnordered"
	case LessOrEqual:
		return "LessOrEqual"
	case LessOrGreater:
		return "LessOrGreater"
	case LessOrUnordered:
		return "LessOrUnordered"
	case GreaterOrEqual:
		return "GreaterOrEqual"
	case GreaterOrUnordered:
		return "GreaterOrUnordered"

	// 3位掩码
	case NotEqual:
		return "NotEqual"
	case NotLess:
		return "NotLess"
	case NotGreater:
		return "NotGreater"
	case NotUnordered:
		return "NotUnordered"

	// 4位掩码
	case Always:
		return "Always"
	}

	// 无效的
	return fmt.Sprintf("Invalid (%#x)", c)
}

func (CCMask) CanBeAnSSAAux() {}
